<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
	</head>
	<body>
		<script>
			//封装Vue构造函数
			function Vue({ data }) {
				this._data = data;

				//数据代理
				for (let key in this._data) {
					Object.defineProperty(this, key, {
						get: function ProxyGetter() {
							return this._data[key];
						},
						set: function ProxySetter(value) {
							this._data[key] = value;
						},
					});
				}

				//调用数据劫持的函数
				observe(this._data);
			}

			//封装一个函数专门用来对某个对象做数据劫持
			function observe(data) {
				//判断如果data不是对象，则不再劫持
				if (typeof data !== "object" || data === null) {
					return;
				}

				//数据劫持的核心
				defineProperty(data);
			}

			function defineProperty(data) {
				for (let key in data) {
					let value = data[key];

					//判断value是不是对象，如果是对象则还要深层次劫持
					observe(value);

					//数据劫持的核心代码
					Object.defineProperty(data, key, {
						get: function ReactiveGetter() {
							console.log("getter");
							return value;
						},
						set: function ReactiveSetter(newVal) {
							console.log("setter");
							value = newVal;
						},
					});
				}
			}

			//实例化Vue
			const vm = new Vue({
				data: {
					name: "laowang",
					age: 18,
					sex: "男",
					score: {
						ch: 100,
						en: 90,
					},
				},
			});
			console.log(vm, "vm");
		</script>
	</body>
</html>
